package mark.tom.friend.presenter;

import com.alibaba.android.arouter.facade.annotation.Autowired;

import java.util.List;
import java.util.concurrent.Callable;

import javax.inject.Inject;

import io.reactivex.Observable;
import io.reactivex.ObservableSource;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.annotations.NonNull;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;
import mark.tom.friend.bean.bo.ConfigRecordBO;
import mark.tom.friend.bean.db.ConfigRecordDO;
import mark.tom.friend.bean.db.ConfigRecordDODao;
import mark.tom.friend.bean.db.DaoSession;
import mark.tom.friend.contract.AppConfigContract;

import static mark.tom.friend.consts.BundleKeyConsts.BUNDLE_KEY_APP_CONFIG_CONTENT;
import static mark.tom.friend.consts.BundleKeyConsts.BUNDLE_KEY_APP_CONFIG_GROUP;
import static mark.tom.friend.consts.BundleKeyConsts.BUNDLE_KEY_APP_NAME;
import static mark.tom.friend.consts.BundleKeyConsts.BUNDLE_KEY_APP_PACKAGE_NAME;

public class AppConfigPresenter implements AppConfigContract.Presenter {

    public final static int REQUEST_CODE_CAPTURE = 1001;

    private AppConfigContract.View mView;

    @Autowired(name = BUNDLE_KEY_APP_NAME) public String appInfoName;
    @Autowired(name = BUNDLE_KEY_APP_PACKAGE_NAME) public String appPackageName;
    @Autowired(name = BUNDLE_KEY_APP_CONFIG_GROUP) public String appConfigGroupName;
    @Autowired(name = BUNDLE_KEY_APP_CONFIG_CONTENT) public String appConfigContent;

    private ConfigRecordDODao configRecordDODao;
    private ConfigRecordBO.ConfigRecordDOConvert configRecordDOConvert;

    @Inject AppConfigPresenter(AppConfigContract.View mView, DaoSession mDaoSession) {
        this.mView = mView;
        this.configRecordDODao = mDaoSession.getConfigRecordDODao();
    }

    @Inject void init() {
        configRecordDOConvert = new ConfigRecordBO.ConfigRecordDOConvert();
    }

    @Override
    public void onStart() {
        // 显示基础信息
        mView.showAppConfigInfo(appInfoName, appConfigGroupName, appConfigContent);
        // 加载配置记录数据
        mView.refreshRecordListView();
    }

    @Override
    public Observable<ConfigRecordBO> listConfigRecord() {
        return Observable
                .defer(new Callable<ObservableSource<Long>>() {
                    @Override public ObservableSource<Long> call() {
                        return Observable.just(1L);
                    }
                })
                .map(new Function<Long, List<ConfigRecordDO>>() {
                    @Override public List<ConfigRecordDO> apply(@NonNull Long s) {
                        return configRecordDODao.queryBuilder()
                                .where(ConfigRecordDODao.Properties.Group.eq(appConfigGroupName)
                                        , ConfigRecordDODao.Properties.PackageName.eq(appPackageName))
                                .orderDesc(ConfigRecordDODao.Properties.Id)
                                .list();
                    }
                })
                .flatMap(new Function<List<ConfigRecordDO>, ObservableSource<ConfigRecordDO>>() {
                    @Override public ObservableSource<ConfigRecordDO> apply(@NonNull List<ConfigRecordDO> appConfigDOs) {
                        return Observable.fromIterable(appConfigDOs);
                    }
                })
                .map(new Function<ConfigRecordDO, ConfigRecordBO>() {
                    @Override public ConfigRecordBO apply(@NonNull ConfigRecordDO configRecordDO) {
                        return configRecordDOConvert.convert(configRecordDO);
                    }
                })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    @Override
    public Observable<ConfigRecordBO> saveConfigRecord(String title, String content) {
        ConfigRecordDO configRecordDO = new ConfigRecordDO();
        configRecordDO.setContent(content);
        configRecordDO.setTitle(title);
        configRecordDO.setPackageName(appPackageName);
        configRecordDO.setGroup(appConfigGroupName);
        return Observable.just(configRecordDO)
                .map(new Function<ConfigRecordDO, ConfigRecordBO>() {
                    @Override
                    public ConfigRecordBO apply(ConfigRecordDO configRecordDO) {
                        configRecordDODao.save(configRecordDO);
                        return configRecordDOConvert.convert(configRecordDO);
                    }
                })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    @Override
    public Observable<Boolean> deleteConfigRecord(Long id) {
        return Observable.just(id)
                .map(new Function<Long, Boolean>() {
                    @Override public Boolean apply(@NonNull Long aLong) {
                        configRecordDODao.deleteByKey(aLong);
                        return true;
                    }
                })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    @Override
    public void onResult(int requestCode, String data) {
        if (REQUEST_CODE_CAPTURE != requestCode) {
            return;
        }
        mView.refreshContent(data);
    }

    @Override
    public void onDestroy() {
        mView = null;
    }
}
